<template>
  <div>
    <!-- 小信息展示处理 -->
    <el-row :gutter="10">

        <!-- 实时展示考试人数统计 -->
        <el-col :span="10">

            <el-card>
                <div slot="header">考试进程</div>
                <div>
                    <!-- 饼图 -->
                    <pieCharts :willExamTotal="willExamTotal" :doingExamTotal="doingExamTotal" :leaveExamTotal="leaveExamTotal"></pieCharts>
                    <span style="float:right" class="cardFooter">完成情况：{{leaveExamTotal}}/{{personTotalNum}}</span>
                </div>
                
            </el-card>

        </el-col>

        <!-- 播报 -->
        <el-col :span="10">

            <el-card>

                <div slot="header">消息：</div>
                <div class="text-container" >
                    <transition class="inner-container2" name="slide" mode="out-in">
                        <p class="text" :key="text.id">{{text.val}}</p>
                    </transition>
                    <transition class="inner-container2" name="slide" mode="out-in">
                        <p class="text" :key="text2.id">{{text2.val}}</p>
                    </transition>
                    <transition class="inner-container2" name="slide" mode="out-in">
                        <p class="text" :key="text3.id">{{text3.val}}</p>
                    </transition>
                </div>

            </el-card>
            
        </el-col>

        <!-- 疑似违规学生列表 -->
        <el-col :span="4">
            <el-card>
                <div slot="header">疑似违规学生</div>
                <div>
                    <el-badge :value="violationTotalNum" class="item">
                        <el-button size="small" @click="dealViolation">处理</el-button>
                    </el-badge>
                </div>
            </el-card>
        </el-col>

    </el-row>
    <!-- 每个学生的状况 -->
    <el-row :gutter="10" style="margin-top: 20px">

        <el-col :span="24">

            <el-card>
                <div slot="header">考生考试状态监测</div>
                <div>
                            <!-- 学号，姓名，考试进度 -->
                    <el-tabs v-model="activeName" @tab-click="ceshi">
                        <el-tab-pane label="未开始" name="-1"></el-tab-pane>
                        <el-tab-pane label="进行中" name="0"></el-tab-pane>
                        <el-tab-pane label="已结束" name="1"></el-tab-pane>
                    </el-tabs>

                    <!-- 搜索框 -->
                    <el-form :inline="true" :model="examStudentVo" class="demo-form-inline">
                        <el-form-item label="学号">
                            <el-input v-model="examStudentVo.studentId" placeholder="请输入学号" clearable>></el-input>
                        </el-form-item>
                        <el-form-item label="姓名">
                            <el-input v-model="examStudentVo.studentName" placeholder="请输入姓名" clearable>></el-input>
                        </el-form-item>
                        <el-form-item label="性别">
                            <el-select v-model="examStudentVo.sex" placeholder="性别" clearable>
                                <el-option label="男" value=1></el-option>
                                <el-option label="女" value=2></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="年龄">
                            <el-input v-model="examStudentVo.age" placeholder="请输入年龄" clearable>></el-input>
                        </el-form-item>
                        <el-form-item label="是否作弊">
                            <el-select v-model="examStudentVo.isCheated" clearable>
                                <el-option label="作弊" value="true"></el-option>
                                <el-option label="没作弊" value="false"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="onSubmit">查询</el-button>
                            <el-button type="warning" @click="clearConnent">清空</el-button>
                        </el-form-item>
                    </el-form>

                    <div style="margin-top: 20px">
            
                        <!-- 考试信息表 -->
                        <el-table style="width: 100%" border :data="list"
                            :row-class-name="tableRowClassName"
                            :header-cell-style="{background:'#F2F6FC',color:'#606266'}"
                            :key="cerinfoKey"
                            ref="filterTable"
                        >
                            <el-table-column prop="number" label="学号" width="100">
                            </el-table-column>
                            <el-table-column prop="name" label="姓名" width="100">
                            </el-table-column>
                            <el-table-column prop="prop" label="性别" width="100">
                                <template slot-scope="scope">
                                    <el-tag
                                    :type="scope.row.sex==1? 'warning' : 'danger'"
                                    disable-transitions>{{scope.row.sex==1?'男':'女'}}</el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column prop="age" label="年龄" width="100">
                            </el-table-column>
                            <el-table-column prop="prop" label="是否作弊" width="80" align="center">
                                <template slot-scope="scope">
                                    <el-tag
                                    :type="scope.row.studentConnection.isCheated? 'danger' : 'success'"
                                    disable-transitions>{{scope.row.studentConnection.isCheated?'√':'×'}}</el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column prop="prop" label="是否考试" width="80" align="center">
                                <template slot-scope="scope">
                                    <el-tag v-if="scope.row.studentConnection.isCheated"
                                    type="danger"
                                    disable-transitions>作弊</el-tag>
                                    <el-tag v-else
                                    :type="tagTypeChange(scope.row.studentConnection.isAttended)"
                                    disable-transitions>{{tagTextChange(scope.row.studentConnection.isAttended)}}</el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column prop="prop" label="考试进度" width="200" align="center">
                                <template slot-scope="{row,$index}">
                                    <el-progress :percentage="Math.round(row.studentConnection.progress*100)"></el-progress>
                                </template>
                            </el-table-column>
                            <el-table-column prop="prop" label="操作" width="150" align="center">
                                <template slot-scope="{row,$index}">
                                    <el-button v-if="!row.studentConnection.isCheated" type="danger" @click="sendMessage(row)" size="mini">作弊</el-button>
                                    <el-button size="mini" @click="showDetail(row)">查看</el-button>
                                </template>
                            </el-table-column>
                        </el-table>

                        <!-- 分页器 -->
                        <el-pagination
                            style="margin-top: 20px; text-align: center"
                            :current-page.sync="examStudentVo.current"
                            :total="total"
                            :page-size="examStudentVo.limit"
                            :page-count="7"
                            :page-sizes="[3, 5, 10]"
                            @current-change="getPageList"
                            @size-change="handleSizeChange"
                            layout="prev, pager, next, jumper, ->, sizes, total"
                            >
                        </el-pagination>

                    </div>
                </div>
            </el-card>

        </el-col>

    </el-row>

    <!-- 作弊信息展示 -->
    <el-drawer
        title="我是标题"
        :visible.sync="drawer"
        :with-header="false"
        direction="rtl"
        size="50%">

        <el-row :gutter="24">
            <el-col :span="24" style="margin-bottom: 20px">

                <!-- 考试基本信息展示 -->
                <el-card class="pre-exam">

                <div><strong>姓名：{{singleStudentInfo.name}}</strong></div>
                <div><strong>学号：{{singleStudentInfo.number}}</strong></div>
                <!-- 走马灯 -->
                <div v-if="singleStudentInfo.faceViolations">
                    <span class="demonstration">疑似违规图片
                        <el-button type="danger" @click="drawerZuobi(singleStudentInfo)" size="mini">作弊</el-button>
                        <el-button type="warning" size="mini" @click="dialogVisibleFaceWall = true">照片墙预览</el-button>
                    </span>
                    <el-carousel  :interval="4000" type="card" height="350px">
                    <el-carousel-item v-for="item in singleStudentInfo.faceViolations" :key="item.id">
                        <div class="keyiText">{{item.remark}}</div>
                        <viewer>
                            <img :src="item.faceUrl" style="width: 300px;height: 250px">
                        </viewer>
                        <el-button style="display:block;margin:0 auto" type="danger" icon="el-icon-delete" circle @click="deleteStuViolationImg(item.id)"></el-button>
                    </el-carousel-item>
                    </el-carousel>
                </div>

                
                </el-card>

            </el-col>

        </el-row>

    </el-drawer>

    <el-dialog title="疑似违规学生名单" :visible.sync="dialogTableVisible" style="width:80%">
        <el-table :data="violationList">
            <el-table-column prop="prop" label="头像" width="100">
                <template slot-scope="{row,$index}">
                    <el-avatar shape="square" size="large" :src="row.avatar"></el-avatar>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="80"></el-table-column>
            <el-table-column prop="number" label="学号" width="100"></el-table-column>
            <el-table-column prop="prop" label="操作" width="width">
                <template slot-scope="{row,$index}">
                    <el-button type="warning" @click="sendMessage(row)" size="mini">作弊</el-button>
                    <el-button size="mini" @click="showDetail(row)">查看</el-button>
                    <el-button type="danger" icon="el-icon-delete" circle @click="deleteViolation(row)"></el-button>
                </template>
            </el-table-column>
        </el-table>
    </el-dialog>

    <!-- 照片墙 -->
    <el-dialog
        title="照片墙"
        :visible.sync="dialogVisibleFaceWall"
        width="width"
        :before-close="dialogBeforeClose">
        <div>
            <el-row :gutter="6" class="spacing manyImg">
                <el-col :span="20" :push="2">
                    <div @click.stop class="manyImgShow">
                        <el-image v-for="(item,index) in this.singleStudentInfo.faceViolations"
                        :key="index"
                        :src="item.faceUrl"
                        alt=""
                        @click="clickHandler"
                        :preview-src-list="fileImges"
                        class="showElImg"
                        >
                        </el-image> 
                    </div> 
                </el-col> 
            </el-row>
        </div>
        <div slot="footer">
            <el-button @click="dialogVisibleFaceWall = false">取 消</el-button>
            <el-button type="danger" @click="drawerZuobi(singleStudentInfo)" size="mini">作弊</el-button>
        </div>
    </el-dialog>
  </div>
</template>

<script>
import { getTeacherId } from '@/api/user'
import pieCharts from './card/pieChart'
export default {
    name:'invigilationDetail',
    components:{
        pieCharts,
    },
    data() {
        return {
            // 照片墙显示问题
            dialogVisibleFaceWall: false,
            // 作弊信息展示页
            drawer: false,
            //当前看中状态
            activeName: '-1',
            // 考试信息
            exam_info:{},
            // 学生参与考试状态，人数
            willExamTotal:0,
            doingExamTotal:0,
            leaveExamTotal:0,
            // socket消息
            msg:{},
            // 学生状态数据集
            list:[],
            // 违规学生信息
            violationList:[],
            // 获取信息列表的body条件
            examStudentVo:{
                current:1,
                limit:5,
                examId:'',
                studentId:null,
                studentName:null,
                sex:null,
                age:null,
                //是否作弊
                isCheated:null,
                //是否以阅卷，-1,0,1
                isMarked:null,
                // 是否已参加考试，-1,0,1
                isAttended:-1,
            },
            // 总数
            total:0,
            arr: ['欢迎老师上线'],
            // 消息数组的定位
            number: 0,
            number2: 1,
            number3: 2,
            // 单人作弊（或者无作弊）信息合集
            singleStudentInfo:{},
            // 违规学生处理界面dialog
            dialogTableVisible: false,
            // 定时器
            timer:null,
            // 解决表格不渲染问题
            cerinfoKey:1,
        }
    },
    mounted() {
        this.exam_info = JSON.parse(this.$route.query.exam_info);
        this.examStudentVo.examId = this.exam_info.id;
        this.openSocket();
        this.getPageList();
        this.getStudentEnterTotal();
        this.getViolationList();
        this.getStudentMessageCenter();
        this.startMove();
        this.timer = setInterval(this.circleTimer, 10000);
    },
    beforeDestroy() {
      clearInterval(this.timer);
    },
    computed:{
        // 违规人数统计
        violationTotalNum(){
            return this.violationList.length;
        },
        // 总人数
        personTotalNum(){
            return this.willExamTotal+this.doingExamTotal+this.leaveExamTotal;
        },
        //播报内容
        text() {
            return {
                id: this.number,
                val: this.arr[this.number]
            }
        },
        text2() {
            return {
                id: this.number2,
                val: this.arr[this.number2]
            }
        },
        text3() {
            return {
                id: this.number3,
                val: this.arr[this.number3]
            }
        },
    },
    methods: {
        // 获得信息
        async getStudentMessageCenter(){
            let result = await this.$API.invigilation.getAllStudentOnlineStatusOfExam(this.exam_info.id);
            if(result.code==20000){
                var list = result.data.list;
                list.map((item,index)=>{
                    if(this.arr.length>=8){
                        // 不让数组长度太长
                        this.arr.shift();
                    }
                    if(item.online){
                        // 上线
                        this.arr.push(
                            item.number+item.name+' 已上线'
                        )
                    }else{
                        // 离线
                        this.arr.push(
                            item.number+item.name+' 已离开考试'
                        )
                    }
                });
            }
        },
        // 删除无关的违规照片
        async deleteStuViolationImg(id){
            let result = await this.$API.invigilation.deleteFaceViolation(id);
            if(result.code==20000){
                var newArray = this.singleStudentInfo.faceViolations.filter(item => item.id !== id);
                this.singleStudentInfo.faceViolations = newArray;
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
            }
        },
        // 删除该条疑似违规信息
        deleteViolation(row){
            //弹框
            this.$confirm('你确定删除该条疑似人脸违规记录吗', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(async() => {
                //当用户点击确定按钮时会触发
                //向服务器发送请求
                let result = await this.$API.invigilation.deleteStudentFaceViolation(this.exam_info.id,row.id);
                //如果删除成功
                if(result.code==20000){
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    //再次获取题库列表
                    this.getViolationList();
                }
                }).catch(() => {
                //当用户点击取消按钮时会触发
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });          
            });
        },
        // 打开有疑似违规的学生名单
        dealViolation(){
            this.dialogTableVisible = true;
            this.getViolationList();
        },
        // 查看里的作弊按钮
        drawerZuobi(singleStudentInfo){
            this.drawer = false;
            this.dialogVisible = false
            this.sendMessage(singleStudentInfo);
        },
        // 查看按钮
        async showDetail(row){
            // 清空当前singleStudentInfo
            this.singleStudentInfo = {};
            // 把学生信息复制一份
            this.singleStudentInfo = row;
            // 查询是否有违规图片集
            let result = await this.$API.invigilation.getStudentFaceViolation(this.exam_info.id,row.id);
            if(result.code==20000){
                this.singleStudentInfo['faceViolations'] = result.data.faceViolations;
                this.drawer = true;
            }
        },
        // 获得所有人脸违规学生的信息
        async getViolationList(){
            let result = await this.$API.invigilation.getAllFaceViolationStudents(this.exam_info.id);
            if(result.code==20000){
                this.violationList = result.data.students;
            }
        },
        // 实现消息循环展示的东西
        startMove() {
            let timer = setTimeout(() => {
                if (this.number === this.arr.length-1) {
                this.number = 0;
                } else {
                this.number += 1;
                }
                if (this.number2 === this.arr.length-1) {
                this.number2 = 0;
                } else {
                this.number2 += 1;
                }
                if (this.number3 === this.arr.length-1) {
                this.number3 = 0;
                } else {
                this.number3 += 1;
                }
                this.startMove();
            }, 2000)
        },
        // 用来定时刷新需要周期更新的数据
        circleTimer() {
            this.getStudentEnterTotal();
            this.getPageList();
            this.getViolationList();
        },
        // 清空按钮
        clearConnent(){
            this.deleteSearch();
            this.getPageList();
        },
        ceshi(){
            //要改变attended值
            this.examStudentVo.isAttended = parseInt(this.activeName);
            this.examStudentVo.current = 1;
            this.getPageList();
        },
        tableRowClassName({row, rowIndex}) {
            if (rowIndex%2 === 1) {
                return 'success-row';
            }
            return '';
        },
        //当分页器某一页需要展示数据条数变化时触发
        handleSizeChange(limit){
            this.examStudentVo.limit = limit;
            this.getPageList();
        },
        // 洗刷刷把空字符串全部弄成null
        clearSearch(){
            if(this.examStudentVo.studentId==''){
                this.examStudentVo.studentId = null;
            }
            if(this.examStudentVo.studentName==''){
                this.examStudentVo.studentName = null;
            }
            if(this.examStudentVo.sex==''){
                this.examStudentVo.sex = null;
            }
            if(this.examStudentVo.age==''){
                this.examStudentVo.age = null;
            }
            if(this.examStudentVo.isCheated==''){
                this.examStudentVo.isCheated = null;
            }
        },
        // 恢复默认状态
        deleteSearch(){
            this.examStudentVo.current = 1;
            this.examStudentVo.limit = 5;
            this.examStudentVo.studentId = null;
            this.examStudentVo.studentName = null;
            this.examStudentVo.sex = null;
            this.examStudentVo.age = null;
            this.examStudentVo.isCheated = null;
        },
        //搜索
        onSubmit(){
            //重新调用获取列表函数
            this.getPageList();
        },
        // 翻译参加考试的值
        tagTextChange(isAttended){
            if(isAttended==-1) return '未参加';
            else if(isAttended==0) return '考试中';
            else if(isAttended==1) return '已结束';
        },
        // 根据参加考试的值，改变tag：type
        tagTypeChange(isAttended){
            if(isAttended==-1) return 'info';
            else if(isAttended==0) return 'warning';
            else if(isAttended==1) return 'success';
        },
        // 获取学生信息数据集
        // 三种都差不多
        async getPageList(){
            this.clearSearch();
            //原因是后端是从0开始的
            let examBody = {...this.examStudentVo};
            examBody.current = examBody.current-1;
            // 性别好像得字符串转整型
            if(examBody.sex!=null){
                examBody.sex = parseInt(this.examStudentVo.sex);
            }
            let result = await this.$API.invigilation.getAllStudentForExam(examBody);
            if(result.code==20000){
                this.list = [];
                this.list = result.data.rows;
                this.total = result.data.total;
                this.cerinfoKey += 1;
            }
        },
        // 刷新考生在线人数
        async getStudentEnterTotal(){
            let result = await this.$API.invigilation.getAllStudentAttendStatusOfExam(this.exam_info.id);
            if(result.code==20000){
                var array = result.data.result;
                this.willExamTotal=0;
                this.doingExamTotal=0;
                this.leaveExamTotal=0;
                for(var i=0;i<array.length;i++){
                    if(array[i].attend==-1){
                        this.willExamTotal = array[i].number;
                    }
                    if(array[i].attend==0){
                        this.doingExamTotal = array[i].number;
                    }
                    if(array[i].attend==1){
                        this.leaveExamTotal = array[i].number;
                    }
                }
            }
        },
        // 作弊播报
        async broadcast(){
            // 处理字符串
            var messageArr = this.msg.singleId.split('-');
            // 学生id
            var studentNum = messageArr[0];
            // 拼接信息
            let studentSingleText = {};
            // 调用接口获取当前学生所有信息
            let result = await this.$API.invigilation.getStudentById(studentNum);
            if(result.code==20000){
                studentSingleText = result.data.student;
                // 为了实现消息不那么多，根据消息累计数量，选择把当前第一个消息销毁
                if(this.arr.length>7){
                    this.arr.shift();
                }
                // 在此处拼接html代码
                var str = '学生'+studentSingleText.number+' '+ studentSingleText.name;
                if(this.msg.msgType==2){
                    str += '被判作弊！！';
                } else if(this.msg.msgType==0){
                    str += '已上线';
                }
                // 数组末尾添加新信息
                this.arr.push(str);
            }
        },
        // 打开连接
        async openSocket() {
            let that = this;
            if(typeof(WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            }else{
                console.log("您的浏览器支持WebSocket");
                //实现化WebSocket对象，指定要连接的服务器地址与端口  建立连接
                var singleId = '';
                let result = await getTeacherId();
                if(result.code==20000){
                    singleId = result.data.teacherId;
                }
                singleId += '-'+that.exam_info.id + '-1';
                // var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;
                var socketUrl="ws://jnexam.natapp1.cc/webSocket/web-socket-server/"+singleId;
                if(that.socket != null){
                    that.socket.close();
                    that.socket=null;
                }
                that.socket = new WebSocket(socketUrl);
                //替代全局里的ws，方便调用
                that.global.setWs(that.socket);
                //打开事件
                that.socket.onopen = function() {
                    console.log("websocket已打开");
                    //socket.send("这是来自客户端的消息" + location.href + new Date());
                };
                //获得消息事件
                that.socket.onmessage = function(msg) {
                    var serverMsg = "收到服务端信息：" + msg.data;
                    console.log(serverMsg);
                    //发现消息进入    开始处理前端触发逻辑
                    that.msg = JSON.parse(msg.data);
                    if(that.msg.msgType==0){
                        // 考试人数变化
                        that.getStudentEnterTotal();
                        that.getPageList();
                        // 有考生进入考试
                        that.broadcast();
                    }else if(that.msg.msgType==2){
                        // 有人被判作弊
                        // 播报一下
                        that.broadcast();
                    }
                };
                //关闭事件
                that.socket.onclose = function() {
                    console.log("websocket已关闭");
                    that.getStudentEnterTotal();
                };
                //发生了错误事件
                that.socket.onerror = function() {
                    console.log("websocket发生了错误");
                }
            }
        },
        // 发送消息
        async sendMessage(row) {
            //弹框
            this.$confirm(`你确定判定${row.name}同学作弊吗`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(async() => {
                //当用户点击确定按钮时会触发
                if(typeof(WebSocket) == "undefined") {
                    console.log("您的浏览器不支持WebSocket");
                }else {
                    // console.log("您的浏览器支持WebSocket");
                    var singleId = '';
                    singleId = row.id + '-' + this.exam_info.id + '-0';
                    // toUserId += '-'+row.id + '-0';
                    var msg = '{"singleId":"'+singleId+'","msgInfo":"学生作弊","msgType":2}';
                    console.log(msg);
                    this.global.ws.send(msg);
                }
                }).catch(() => {
                //当用户点击取消按钮时会触发
                this.$message({
                    type: 'info',
                    message: '已取消'
                });          
            });
            
        },
    },
    watch:{
        //监听activeName，只要切换了状态，输入框内容应该为空
        activeName:{
            handler(){
                // 要先清空查询条件
                this.deleteSearch();
                // 查询
                this.onSubmit();
            }
        },
  },
}
</script>

<style>
.cardFooter{
    font-size: 12px;
    font-style: italic;
    font-family: "楷体";
}
.text{
    font-size: 12px;
    font-style: italic;
    font-family: "楷体";
}
.slide-enter-active, .slide-leave-active {
  transition: all 0.5s linear;
}
.slide-leave-to {
  transform: translateY(-20px);
}
.slide-enter {
  transform: translateY(20px);
}
.item {
  margin-top: 10px;
  margin-right: 40px;
}
.pre-exam div {
    line-height: 42px;
    color: #555555;
}
.el-carousel__item h3 {
    color: #475669;
    font-size: 14px;
    opacity: 0.75;
    line-height: 150px;
    margin: 0;
}
.el-carousel__item:nth-child(2n) {
    background-color: #99a9bf;
}

.el-carousel__item:nth-child(2n+1) {
    background-color: #d3dce6;
}
</style>

<style scoped>
>>>.el-carousel__button{
    width:10px;
    height:10px;
    background:red;
    border-radius:50%;
}
.demonstration{
    font-size: 16px;
    color: #d3dce6;
}
.keyiText{
    background-color: crimson;
}
.manyImgShow {
    height: 80px; 
    height: auto !important;
}
.showElImg{
  /*display: inline-block;*/
 width: 150px;
 height: 125px;
 padding-right: 10px;
}
</style>
